package cz.pproproj.aaservice.guimodule.rest;

import cz.pproproj.aaservice.guimodule.model.Credentials;
import org.springframework.http.HttpHeaders;

import javax.xml.bind.DatatypeConverter;
import java.util.List;

public class AuthHeaderParser {

    private static final String BASIC_AUTH_PREFIX = "Basic ";
    private static final String BEARER_AUTH_PREFIX = "Bearer ";

    public Credentials parse(HttpHeaders headers) {
        String authHeader = getAuthHeader(headers);
        if (authHeader == null || authHeader.isEmpty()) {
            return null;
        }

        if (authHeader.startsWith(BASIC_AUTH_PREFIX)) {
            return parseBasicHeader(authHeader);
        } else if (authHeader.startsWith(BEARER_AUTH_PREFIX)) {
            return parseBearerHeader(authHeader);
        } else {
            return null;
        }
    }

    private Credentials parseBasicHeader(String authHeader) {
        String credentials = authHeader.substring(BASIC_AUTH_PREFIX.length()).trim();
        byte[] asBytes = DatatypeConverter.parseBase64Binary(credentials);
        credentials = new String(asBytes);

        int colonIdx = credentials.indexOf(":");
        if (colonIdx < 1) { // there should be at least one character before colon
            return null;
        }
        String username = credentials.substring(0, colonIdx);
        String password = credentials.substring(colonIdx + 1);
        return new Credentials(username, password);
    }

    private Credentials parseBearerHeader(String authHeader) {
        String token = authHeader.substring(BEARER_AUTH_PREFIX.length()).trim();
        if (token == null || token.isEmpty()) {
            return null;
        } else {
            return new Credentials(token);
        }
    }

    private String getAuthHeader(HttpHeaders headers) {
        if (headers == null) {
            throw new IllegalArgumentException("Given HTTP headers are null!");
        }
        List<String> authHeaders = headers.get("Authorization");
        if (authHeaders == null || authHeaders.isEmpty()) {
            return null;
        }
        return authHeaders.get(0);
    }
}
